use std::net::SocketAddr;

// tests/user_admin_test.rs
use axum::body::Body;
use axum::Router;
use axum::extract::ConnectInfo;
use http::{header::CONTENT_TYPE, Request, StatusCode};

use serde_json::json;
use sheisright::web::App;   // 注意路径
use sheisright::rbac;
use tower::ServiceExt;
use axum::body::to_bytes;

#[tokio::test]
async fn admin_can_create_user_normal_user_cannot() {
    use serde_json::json;

    // 0. 确保 RBAC 表已加载
    rbac::create_enforcer().await;

    let app = App::new().await.unwrap().build_router().await.layer(axum::Extension(ConnectInfo(
        SocketAddr::from(([127, 0, 0, 1], 3000)),
    )));

    /* ---------- 管理员流程 ---------- */
    // 1. 登录管理员
    let admin_cookie = login_and_cookie(&app, "configer", "hunter42").await;

    let new_username = "ceshi4";
    // 2. 管理员创建用户
    let create_resp = app.clone()
        .oneshot(
            Request::builder()
                .method("POST")
                .uri("/adduser")
                .header("cookie", &admin_cookie)
                .header(CONTENT_TYPE, "application/json")
                .body(Body::from(
                    json!({
                        "id": 0,
                        "username": new_username,
                        "email": "alice@example.com",
                        "password": "123456",
                        "role": "auditor",
                        "status": "active",
                        "created_at": "20251104",
                        "avatar": "",
                        "accessdir": "",
                        "uploadperm": true,
                        "downloadperm": true,
                    })
                    .to_string(),
                ))
                .unwrap(),
        )
        .await
        .unwrap();
    // ✅ 新增：把后端错误信息打出来
    if !create_resp.status().is_success() {
        let body = to_bytes(create_resp.into_body(), 1024*1024).await.unwrap();
        panic!("server error: {}", String::from_utf8_lossy(&body));
    }
    //assert_eq!(create_resp.status(), StatusCode::CREATED);
    assert_eq!(create_resp.status(), 200);

    /* ---------- 普通用户流程 ---------- */
    // 3. 用刚创建的用户登录
    let user_cookie = login_and_cookie(&app, new_username, "123456").await;

    // 4. 普通用户尝试创建别人 → 应 403
    let forbidden_resp = app
        .oneshot(
            Request::builder()
                .method("POST")
                .uri("/adduser")
                .header("cookie", &user_cookie)
                .header(CONTENT_TYPE, "application/json")
                .body(Body::from(
                    json!({
                        "id": 0,
                        "username": "ceshi3",
                        "email": "alice@example.com",
                        "password": "123456",
                        "role": "configer",
                        "status": "active",
                        "created_at": "20251104",
                        "avatar": "",
                        "accessdir": "",
                        "uploadperm": true,
                        "downloadperm": true,
                    })
                    .to_string(),
                ))
                .unwrap(),
        )
        .await
        .unwrap();
    assert_eq!(forbidden_resp.status(), StatusCode::FORBIDDEN);
}

/* ---------- 辅助：登录 -> 返回 Set-Cookie ---------- */
async fn login_and_cookie(app: &Router, user: &str, pwd: &str) -> String {
    let resp = app.clone()
        .oneshot(
            Request::builder()
                .method("POST")
                .uri("/login")
                .header(CONTENT_TYPE, "application/x-www-form-urlencoded")
                .body(Body::from(format!("username={user}&password={pwd}")))
                .unwrap(),
        )
        .await
        .unwrap();
    assert!(resp.status().is_redirection()); // 303
    resp.headers()["set-cookie"].to_str().unwrap().to_owned()
}